import { Accordion, Alert, Link, Text, Tabs } from '@aws-amplify/ui-react';
import { Example, ExampleCode } from '@/components/Example';
import { InstallScripts, TerminalCommand } from '@/components/InstallScripts';
import { ReactNativeSafeAreaContextInstallation } from '@/components/ReactNativeSafeAreaContextInstallation';
import { InlineFilter } from '@/components/InlineFilter';
import QuickStartPullWeb from './quick-start-pull.web.mdx';
import QuickStartInstallWeb from './quick-start-install.web.mdx';
import QuickStartAddWeb from './quick-start-add.web.mdx';
import TroubleshootingWeb from './trouble-shooting-alert.web.mdx';
import AmplifyCLI from './amplify-cli.mdx';


#### Step 1. Configure backend

<InlineFilter filters={['android']}>
  Run `amplify add auth` to configure how you want the Authenticator and its associated Cognito resources to behave. If you want more details on all of the options available in this step, please check out the Amplify Android Auth [getting started page](https://docs.amplify.aws/lib/auth/getting-started/q/platform/android/#set-up-backend-resources) or the more detailed Amplify CLI [documentation](https://docs.amplify.aws/cli/auth/overview/).

  <TerminalCommand command="amplify add auth" />
  <TerminalCommand command="amplify push" />

  Alternatively, if you already have an Amplify app set up that you want to import the backend from, run `amplify pull` to sync your `amplifyconfiguration.json` with your cloud backend:

  <TerminalCommand command="amplify pull" />

  This will update your `amplifyconfiguration.json` with your latest backend configuration for the Authenticator.
</InlineFilter>
<InlineFilter filters={['flutter']}>
  <AmplifyCLI />

  Then run `amplify pull` to sync your `amplifyconfiguration.json` with your cloud backend:

  ```shell
  amplify pull
  ```

  This will update your `amplifyconfiguration.json` with your latest backend configuration for the Authenticator.
</InlineFilter>
<InlineFilter filters={['react', 'svelte']}>
  <QuickStartPullWeb />
</InlineFilter>
<InlineFilter filters={['react-native']}>
  <AmplifyCLI />

  Now that you have the Amplify CLI installed, you can set up your Amplify project by running `amplify init` in your project's root directory. Then run `amplify add auth` and follow the prompts to add authentication to your backend configuration.

  _If you have an existing backend, run `amplify pull` to sync your `aws-exports.js` with your cloud backend._

  You should now have an `aws-exports.js` file in your `src/` directory with your latest backend configuration.
</InlineFilter>
<InlineFilter filters={['swift']}>
  <AmplifyCLI />

  Run `amplify add auth` to configure how you want the Authenticator and its associated Cognito resources to behave. If you want more details on all of the options available in this step, please check out the Amplify for Swift Library Authentication [getting started page](https://docs.amplify.aws/lib/auth/getting-started/q/platform/ios/#set-up-backend-resources).

  <TerminalCommand command="amplify add auth" />
  <TerminalCommand command="amplify push" />

  Alternatively, if you have an existing backend, run `amplify pull` to sync your `amplifyconfiguration.json` file:

  <TerminalCommand command="amplify pull" />
</InlineFilter>


#### Step 2. Install dependencies

<InlineFilter filters={['android']}>
  The Authenticator component is built using [Jetpack Compose](https://developer.android.com/jetpack/compose). Enable Jetpack Compose by adding the following to the `android` section of your **app**'s `build.gradle` file:

  ```groovy
  compileOptions {
      // Support for Java 8 features
      coreLibraryDesugaringEnabled true
      sourceCompatibility JavaVersion.VERSION_1_8
      targetCompatibility JavaVersion.VERSION_1_8
  }
  buildFeatures {
      compose true
  }
  composeOptions {
    kotlinCompilerExtensionVersion '1.5.3'
  }
  ```

  Add the following dependencies to your **app**'s `build.gradle` file and click "Sync Now" when prompted:

  ```groovy
  dependencies {    
      // Authenticator dependency
      implementation 'com.amplifyframework.ui:authenticator:1.4.0'
      
      // Support for Java 8 features
      coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
  }
  ```
</InlineFilter>
<InlineFilter filters={['flutter']}>
  Add [amplify_authenticator](https://pub.dev/packages/amplify_authenticator), [amplify_flutter](https://pub.dev/packages/amplify_flutter), and [amplify_auth_cognito](https://pub.dev/packages/amplify_auth_cognito) packages as a dependencies.

  <ExampleCode>
  ```yaml{6-8}
    environment:
      sdk: ^3.3.0
      flutter: '>=3.19.0'

    dependencies:
      amplify_flutter: ^2.0.0
      amplify_auth_cognito: ^2.0.0
      amplify_authenticator: ^2.0.0
  ```
  </ExampleCode>
</InlineFilter>
<InlineFilter filters={['react', 'svelte']}>
  <QuickStartInstallWeb />
</InlineFilter>
<InlineFilter filters={['react-native']}>
  <InstallScripts />

  <ReactNativeSafeAreaContextInstallation />

  If your project will support Federated Sign In using the React Native `Authenticator` the `@aws-amplify/rtn-web-browser` package is also required:

  <TerminalCommand command="npm install @aws-amplify/rtn-web-browser" />

  <Accordion.Container>
    <Accordion.Item value="Accordion-item">
      <Accordion.Trigger>
        Important note for integration with React Native projects using version `0.72` or below
        <Accordion.Icon />
      </Accordion.Trigger>
    <Accordion.Content>
      `@aws-amplify/react-native` and `@aws-amplify/rtn-web-browser` require a minimum iOS deployment target of `13.0`, open the _Podfile_ located in the _ios_ directory and update the `target` value:
      ```diff
      - platform :ios, min_ios_version_supported
      + platform :ios, 13.0
      ```
    </Accordion.Content>
    </Accordion.Item>
  </Accordion.Container>

  Then install the iOS cocoapods by running:

  <InstallScripts command="npx pod-install" framework="react-native" />
</InlineFilter>
<InlineFilter filters={['swift']}>
  Open your project in Xcode and select **File > Add Packages...** and add the following dependencies:

  - [**Amplify Library for Swift**](https://github.com/aws-amplify/amplify-swift): Enter its GitHub URL (`https://github.com/aws-amplify/amplify-swift`), select **Up to Next Major Version** and click **Add Package**

    - Select the following libraries:
      - Amplify
      - AWSCognitoAuthPlugin

  - [**Amplify UI Swift - Authenticator**](https://github.com/aws-amplify/amplify-ui-swift-authenticator): Enter its GitHub URL (`https://github.com/aws-amplify/amplify-ui-swift-authenticator`), select **Up to Next Major Version** and click **Add Package**

    - Select the following library:
      - Authenticator
</InlineFilter>

#### Step 3. Add the Authenticator

<InlineFilter filters={['android']}>
  The quickest way to get started is by wrapping your App component (written in Jetpack Compose) with the Authenticator widget. Once an end-user has created an account & signed in, your content will be displayed.

  In the `onCreate` of your `Application` class, add the Auth plugin before calling `Amplify.configure`.

  ```kotlin
  override fun onCreate() {
      super.onCreate()

      try {
          Amplify.addPlugin(AWSCognitoAuthPlugin())
          Amplify.configure(applicationContext)
          Log.i("MyAmplifyApp", "Initialized Amplify")
      } catch (error: AmplifyException) {
          Log.e("MyAmplifyApp", "Could not initialize Amplify", error)
      }
  }
  ```

  Add the Authenticator to your app by wrapping your component (represented here by the `@Composable` function `SignedInContent`) with the `Authenticator` component.

  ```kotlin
  import android.os.Bundle
  import androidx.activity.ComponentActivity
  import androidx.activity.compose.setContent
  import androidx.compose.foundation.layout.Column
  import androidx.compose.material3.Button
  import androidx.compose.material3.Text
  import androidx.compose.runtime.Composable
  import androidx.compose.runtime.rememberCoroutineScope
  import com.amplifyframework.ui.authenticator.SignedInState
  import com.amplifyframework.ui.authenticator.ui.Authenticator
  import kotlinx.coroutines.launch

  class MainActivity : ComponentActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)

          setContent {
              Authenticator { state ->
                  SignedInContent(state)
              }
          }
      }
  }

  @Composable
  fun SignedInContent(state: SignedInState) {
      val scope = rememberCoroutineScope()
      Column {
          Text("You've signed in as ${state.user.username}")
          Button(onClick = { scope.launch { state.signOut() } }) {
              Text("Sign Out")
          }
      }
  }
  ```
</InlineFilter>
<InlineFilter filters={['flutter']}>
  The quickest way to get started is by wrapping your MaterialApp widget with the Authenticator widget.
  Once an end-user has created an account & signed in, the MaterialApp will be displayed.

  Add the authenticator to your app by wrapping the MaterialApp widget in the Authenticator widget, and then set the MaterialApp's `builder` to `Authenticator.builder()`.

  ```dart{38,40}
  import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
  import 'package:amplify_authenticator/amplify_authenticator.dart';
  import 'package:amplify_flutter/amplify_flutter.dart';
  import 'package:flutter/material.dart';

  import 'amplifyconfiguration.dart';

  void main() {
    runApp(const MyApp());
  }

  class MyApp extends StatefulWidget {
    const MyApp({super.key});

    @override
    State<MyApp> createState() => _MyAppState();
  }

  class _MyAppState extends State<MyApp> {
    @override
    void initState() {
      super.initState();
      _configureAmplify();
    }

    void _configureAmplify() async {
      try {
        await Amplify.addPlugin(AmplifyAuthCognito());
        await Amplify.configure(amplifyconfig);
        safePrint('Successfully configured');
      } on Exception catch (e) {
        safePrint('Error configuring Amplify: $e');
      }
    }

    @override
    Widget build(BuildContext context) {
      return Authenticator(
        child: MaterialApp(
          builder: Authenticator.builder(),
          home: const Scaffold(
            body: Center(
              child: Text('You are logged in!'),
            ),
          ),
        ),
      );
    }
  }
  ```
</InlineFilter>
<InlineFilter filters={['react', 'svelte']}>
  <QuickStartAddWeb />
</InlineFilter>
<InlineFilter filters={['react-native']}>
  The quickest way to get started is by wrapping your application with the Authenticator component.
  Once an end-user has created an account & signed in, the underlying component is rendered with access to the `user`.

  You can use the `Authenticator` component directly, or wrap your app in `withAuthenticator`
  [Higher-Order Component](https://legacy.reactjs.org/docs/higher-order-components.html):

  <Tabs.Container defaultValue="Authenticator">
    <Tabs.List>
      <Tabs.Item value="Authenticator">Authenticator</Tabs.Item>
      <Tabs.Item value="withAuthenticator">withAuthenticator</Tabs.Item>
    </Tabs.List>
    <Tabs.Panel value="Authenticator">
      ```js expoSnack file=../../../../../../examples/react-native/src/features/Authenticator/Basic/Example.tsx

      ```
    </Tabs.Panel>
    <Tabs.Panel value="withAuthenticator">
      ```js expoSnack file=../../../../../../examples/react-native/src/features/Authenticator/WithAuthenticator/Example.tsx

      ```
    </Tabs.Panel>
  </Tabs.Container>
</InlineFilter>
<InlineFilter filters={['swift']}>
  The quickest way to get started is by adding the Authenticator view as the entry point in your application.

  Once an end-user has created an account and/or signed in, the provided content is displayed with access to the user.

  ```swift
  import Amplify
  import Authenticator
  import AWSCognitoAuthPlugin
  import SwiftUI

  @main
  struct MyApp: App {
      init() {
          do {
              try Amplify.add(plugin: AWSCognitoAuthPlugin())
              try Amplify.configure()
          } catch {
              print("Unable to configure Amplify \(error)")
          }
      }

      var body: some Scene {
          WindowGroup {
              Authenticator { state in
                  VStack {
                      Text("Hello, \(state.user.username)")
                      Button("Sign out") {
                          Task {
                              await state.signOut()
                          }
                      }
                  }
              }
          }
      }
  }

  ```
</InlineFilter>

<InlineFilter filters={['react']}>
  <TroubleshootingWeb />
</InlineFilter>
